﻿using System;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Security;
using BLL.Configuration;
using BLL.Models.Users;
using BLL.Security;
using BLL.Services;
using BLL.Services.Books;
using BLL.Services.Users;
using MvcContrib.Sorting;
using MvcContrib.UI.Grid;
using Web.Areas.Admin.Models.Users;
using Web.Infrastructure;
using Web.Infrastructure.Models;
using Web.Infrastructure.Security;
using Web.Models;
using Web.Models.Account;

namespace Web.Controllers
{
    public partial class AccountController : FrontendController
    {
        private readonly IGlobalSettings _context;

        private readonly ISecurityService _securityService;

        private readonly IUsersService _usersService;

        private readonly IEnvironmentContext _environmentContext;

        private readonly Dictionary<AuthenticationStatus, string> _authenticationErrors = new Dictionary
            <AuthenticationStatus, string>
            {
                { AuthenticationStatus.Disabled, @"Ваш аккаунт неактивен!" },
                { AuthenticationStatus.NotVerified, @"Верифицируйте свой аккаунт!" },
                { AuthenticationStatus.PaswordInvalid, @"Пароль не верен!" },
                { AuthenticationStatus.NotFound, @"Пользователь не найден!" }
            };

        public AccountController(
            IGlobalSettings context,
            ISecurityService securityService,
            IUsersService usersService,
            IEnvironmentContext environmentContext)
        {
            _context = context;
            _securityService = securityService;
            _usersService = usersService;
            _environmentContext = environmentContext;
        }

        [HttpGet]
        public virtual ActionResult LogOn()
        {
            return BackBoneView(MVC.Shared.Views.Empty);
        }

        public virtual ActionResult LogOnTemplate()
        {
            return BackBoneView(MVC.Account.Views.LogOn);
        }

        public virtual ActionResult LogOn(LogOnModel model)
        {
            if (!ModelState.IsValid)
            {
                model.Errors = GetErrors;
                return Json(model);
            }

            var status = _securityService.AuthenticateUser(model.Email, model.Password);
            if (_authenticationErrors.ContainsKey(status))
            {
                model.Errors = new List<ErrorModel> { new ErrorModel { Message = _authenticationErrors[status] } };
                return Json(model);
            }

            var cookie = new AuthenticationCookie(model.Email, UserTypes.EndUser);
            model.Login = _usersService.GetUserByEmailOrLogin(model.Email).Login;
            if (model.RememberMe)
            {
                int timeout = _context.Security.PersistentAuthenticationCookieTimeoutDays;
                cookie.Expires = DateTime.Now.AddDays(timeout);
            }
            else
            {
                int timeout = _context.Security.SessionAuthenticationCookieTimeoutHours;
                cookie.Expires = DateTime.Now.AddHours(timeout);
            }

            cookie.AppendToResponse(Response, FormsAuthentication.FormsCookieName, model.RememberMe);

            model.SuccessMessage = "Вы успешно авторизированы!";
            return Json(model);
        }

        public virtual ActionResult Register()
        {
            return new EmptyResult();
        }

        public virtual ActionResult LogOff()
        {
            FormsAuthentication.SignOut();

            return new EmptyResult();
        }


        public virtual ActionResult GetEdit(UserEditModel model)
        {
            var user = _environmentContext.User;
            return Json(user, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public virtual ActionResult Save(EditProfileModel model)
        {
            if (!ModelState.IsValid && model.UserId!=_environmentContext.User.UserId)
            {
                model.Errors = GetErrors;
                return Json(model);
            }
            var user = _environmentContext.User;
            user += model;
            try
            {
                _usersService.Save(user);
                model.SuccessMessage = "User has been successfully updated.";
                return Json(model);
            }
            catch (ServiceException exception)
            {
                ModelState.AddModelError(string.Empty,exception.Message);
                model.Errors = GetErrors;
                return Json(model);
            }
        }

        public virtual ActionResult Edit()
        {
            return View();
        }

        public virtual ActionResult EditTemplate()
        {
            return PartialView();
        }

        public virtual ActionResult Validate(int? userId, string email, string login)
        {
            var idParam = userId.HasValue ? userId.Value : 0;
            var result = _usersService.ValidateUser(idParam, email, login);
            return Json(result);
        }
    }
}
